#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/timerfd.h>
#include <unistd.h>


/*********************************************************
 * 一旦以timerfd_settime()启动了定时器，就可以从相应文件描述符中调用read()来读取定时器的到期信息，
 * 出于这一目的，传给read()的缓冲区必须足以容纳一个无符号8字节整形（uint64_t）数。
 * 在上次使用timerfd_settime()修改设置以后，或是最后一次执行read()后，如果发生了一起到多起定时器到期时间，
 * 那么read()会立即返回，且返回的缓冲区中包含了已发生的到期次数。
 *********************************************************/
int main001(int argc, char const *argv[])
{
    struct itimerspec ts;
    ts.it_value.tv_sec = 1;
    ts.it_value.tv_nsec = 0;
    ts.it_interval.tv_sec = 1;
    ts.it_interval.tv_nsec = 0;

    int fd = timerfd_create(CLOCK_MONOTONIC, 0);
    if (fd == -1)
    {
        perror("timerfd_create");
        exit(EXIT_FAILURE);
    }

    if (timerfd_settime(fd, 0, &ts, NULL) == -1)
    {
        perror("timerfd_settime");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < 100; i++)
    {
        uint64_t numExp;
        ssize_t s = read(fd, &numExp, sizeof(uint64_t));
        if (s != sizeof(uint64_t))
        {
            perror("read");
            exit(EXIT_FAILURE);
        }
        printf("hello world, numExp = %lu\n", numExp);  // numExp = 1,
    }

    exit(EXIT_SUCCESS);

    return 0;
}

int main(int argc, char const *argv[])
{
    struct itimerspec ts;
    ts.it_value.tv_sec = 3;
    ts.it_value.tv_nsec = 0;
    ts.it_interval.tv_sec = 2;
    ts.it_interval.tv_nsec = 0;

    int fd = timerfd_create(CLOCK_MONOTONIC, 0);
    if (fd == -1)
    {
        perror("timerfd_create");
        exit(EXIT_FAILURE);
    }

    if (timerfd_settime(fd, 0, &ts, NULL) == -1)
    {
        perror("timerfd_settime");
        exit(EXIT_FAILURE);
    }

    for (int it = 0; it < 100; it++)
    {
        char buf[512];
        ssize_t s = read(fd, buf, sizeof(buf));
        printf("s = %ld\n", s);
        for (int i = 0; i < s; ++i)
        {
            printf("buf[%d] = %d\n", i, buf[i]); // buf[0]=1, buf[1]=0, ...
        } 

        printf("hello world\n");
    }

    exit(EXIT_SUCCESS);
    return 0;
}
